package org.abstractmeta.commandify.core.command;

import org.abstractmeta.reflectify.Accessor;
import org.abstractmeta.reflectify.MethodInvoker;
import org.abstractmeta.reflectify.Mutator;
import org.abstractmeta.reflectify.Reflectify;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Abstract reflectify
*/
public abstract class AbstractReflectify<T> implements Reflectify<T> {


    private final Class<T> type;

    public AbstractReflectify(Class<T> type) {
        this.type = type;
    }

    protected abstract Map<String, Accessor> getAccessors();

    protected abstract Map<String, Mutator> getMutators();

    @Override
    public Class<T> getType() {
        return type;
    }

    @Override
    public Provider<T> getProvider(Class... argumentTypes) {
        throw new  UnsupportedOperationException();
    }

    @Override
    public List<Provider<T>> getProviders() {
        throw new  UnsupportedOperationException();
    }

    @Override
    public <T1> MethodInvoker<T, T1> getMethodInvoker(Class<T1> methodResultType, String methodName, Class... argumentTypes) {
        throw new  UnsupportedOperationException();
    }

    @Override
    public MethodInvoker<T, Object> getMethodInvoker(String methodName, Class... argumentTypes) {
        throw new  UnsupportedOperationException();
    }

    @Override
    public List<MethodInvoker<T, Object>> getMethodInvokers(String methodName) {
        throw new  UnsupportedOperationException();
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T1> Accessor<T, T1> getAccessor(Class<T1> fieldType, String fieldName) {
        return Accessor.class.cast(getAccessor(fieldName));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Accessor<T, Object> getAccessor(String fieldName) {
        return getAccessors().get(fieldName);
    }




    @Override
    @SuppressWarnings("unchecked")
    public <T1> Mutator<T, T1> getMutator(Class<T1> fieldType, String fieldName) {
        return Mutator.class.cast(getMutators().get(fieldName));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Mutator<T, Object> getMutator(String fieldName) {
        return getMutators().get(fieldName);
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<String> getFieldNames() {
        return new ArrayList(getAccessors().keySet());
    }

    @Override
    public Class getFieldType(String fieldName) {
        throw new  UnsupportedOperationException();
    }

    @Override
    public List<String> getMethodNames() {
        throw new  UnsupportedOperationException();
    }
}
